Repository navigation
vm: render the top-level self as "main", and give remove_method's NameError its receiver - #738
Merged
Merged
Conversation
…eError its receiver
Two residuals another wave routed out of its own cluster, both measured against
ruby 4.0.5 first.
MRI renders an object that carries a singleton class by its identity string, with
exactly one exception: the top-level self is "main". name_err_mesg_to_str
(error.c ruby_4_0:2679-2689) takes the singleton arm, sets the "an instance of "
prefix to empty, and then chooses between rb_any_to_s(obj) and the literal
"main" on `obj == rb_vm_top_self()`. rbgo had the arm and not the exception:
self.nope_xyz
MRI : undefined method 'nope_xyz' for main
rbgo : undefined method 'nope_xyz' for #<Object:0x0000000000000008>
An ordinary object with a singleton was already right, which is what said the
arm itself was fine and only its exception was missing.
The test also pins what must NOT move, and it is the more interesting half: MRI
does NOT dispatch #inspect or #to_s to build that identity. Overriding both on
the receiver changes the message on neither engine -- measured, both directions
-- so this file's existing choice to construct the string rather than send to
the receiver is MRI's choice too, and the test now says so. An error path that
runs user code can recurse or raise again.
Second: Module#remove_method on a name that is not there raises through
rb_name_err_raise (vm_method.c rb_mod_remove_method), whose first argument IS
the exception's receiver. rbgo built the same message through the bare raise()
form and recorded none, so #receiver answered nil where MRI answers the module.
This is one of the 36 bare-raise NameError sites the census in exception.go
counts; it is fixed because the oracle was measured for it, not because bare
raises are wrong in general -- the global-variable ones legitimately record no
receiver.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two residuals another wave routed out of its own cluster, both measured against ruby 4.0.5 first.
The top-level self renders as
mainMRI renders an object that carries a singleton class by its identity string, with exactly one exception: the top-level self is
main.name_err_mesg_to_str(error.cruby_4_0:2679-2689) takes the singleton arm, sets the"an instance of "prefix to empty, and then chooses betweenrb_any_to_s(obj)and the literal"main"onobj == rb_vm_top_self().rbgo had the arm and not the exception:
An ordinary object carrying a singleton was already right, which is what said the arm itself was sound and only its exception was missing.
The half of the test that is more interesting than the fix
MRI does not dispatch
#inspector#to_sto build that identity. Overriding both on the receiver changes the message on neither engine:So this file's existing choice to construct the string rather than send to the receiver is MRI's choice too, and the test now says so rather than leaving it as a comment. An error path that runs user code can recurse or raise again. Measured in both directions before writing it — I was about to "fix" this by dispatching
to_s, and the oracle said no.remove_method's NameError carries its receiverModule#remove_methodon a name that is not there raises throughrb_name_err_raise(vm_method.c,rb_mod_remove_method), whose first argument is the exception's receiver.This is one of the 36 bare-
raise("NameError", …)sites that the census inexception.gocounts (#732). It is fixed because the oracle was measured for it — not because bare raises are wrong in general: the global-variable ones legitimately record no receiver, and#receiverraisingArgumentErrorthere is MRI's own answer.Non-regression, checked rather than assumed
Object.new.nope(no singleton)an instance of Objectinspect/to_s#<Object:0x…>#<Object:0x…>Q.const_get(:Nope)receiverQFull suite green on Go 1.27.1 with
CGO_ENABLED=0;wasip1andjs/wasmbuild;gofmtclean.🤖 Generated with Claude Code